
import 'package:im_app/im/socket/SignalWebSocket.dart';

import '../socket/dto/base/Req.dart';
import '../socket/dto/base/Resp.dart';
import '../socket/dto/business/Login.dart';
import '../socket/dto/business/RpcData.dart';
import '../socket/exception/RpcException.dart';
import '../util/ImSingleton.dart';
import '../util/LoggerUtil.dart';
import 'dto.dart';

class RpcSignalService {

  final _logger = createLogger();
  final SignalWebSocket _signalWebSocket;

  RpcSignalService(this._signalWebSocket);

  // 登录WebRtc信令服务器
  Future<LoginResp> login(loginReq, timeoutSecond) async {
    return _sendDataAndOk("signalLogin", loginReq, LoginResp.fromJson, timeoutSecond?? 60);
  }

  // 创建视频聊天房间
  Future<OkResp> createRoom(webRtcCreateRoomReq, timeoutSecond) async {
    return _sendDataAndOk("roomCreate", webRtcCreateRoomReq, OkResp.fromJson, timeoutSecond?? 60);
  }

  // 进入房间
  Future<WebRtcRoomInfo> joinRoom(webRtcJoinRoomReq, timeoutSecond) async {
    return _sendDataAndOk("roomJoin", webRtcJoinRoomReq, WebRtcRoomInfo.fromJson, timeoutSecond?? 60);
  }

  // 退出房间
  Future<OkResp> exitRoom(webRtcExitRoomReq, timeoutSecond) async {
    return _sendDataAndOk("roomExit", webRtcExitRoomReq, OkResp.fromJson, timeoutSecond?? 60);
  }

  // 发送sdp
  Future<OkResp> sdp(webRtcP2pSdpReq, timeoutSecond) async {
    return _sendDataAndOk("sdp", webRtcP2pSdpReq, OkResp.fromJson, timeoutSecond?? 60);
  }

  // 发送iceCandidate
  Future<OkResp> iceCandidate(webRtcP2pCandidateReq, timeoutSecond) async {
    return _sendDataAndOk("iceCandidate", webRtcP2pCandidateReq, OkResp.fromJson, timeoutSecond?? 60);
  }

  ///发送消息，并得到服务端的明确回复
  Future<T> _sendDataAndOk<T>(String path, Req req, Function fromJson, [int? timeout = 60]) async {
    String? seq = _createSeq();
    RpcData rpcData = RpcData.data(path, req, seq);
    RpcData? resultRpcData = await _signalWebSocket.sendData(rpcData, fromJson, timeout);
    _logger.i("$path success result : ${resultRpcData?.data}", );
    if (resultRpcData?.data is ExceptionResp) {
      var exceptionResp = resultRpcData?.data as ExceptionResp;
      throw RpcException(exceptionResp.errorMsg??'');
    }
    return resultRpcData?.data as T;
  }

  String _createSeq(){
    var seq = ImSingleton.getInstance().seqCreator.create();
    seq = seq??"";
    return seq;
  }
}
